package register

import (
	"gitee.com/goddesszz/gocommon/myutil"
	"github.com/sirupsen/logrus"
	"reflect"
	"sync"
)

// 创建实例对象的工厂
var serviceFactory = make(map[string]func() any)

// 已创建的实例对象缓存
var serviceInstances = make(map[string]any)

var mu sync.Mutex

// RegisterInstance 注册服务实例
// name 服务名，方法内部会将服务名的首字母小写
func RegisterInstance[T any](name string, factory func() T) {
	name = myutil.LowerFirst(name) // 服务名首字母小写

	mu.Lock() // 加锁：确保并发安全
	defer mu.Unlock()

	// 3. 如果serviceFactory已存在，则表示冲突了
	if _, ok := serviceFactory[name]; ok {
		panic("service factory already register, conflict with: " + name)
	}

	serviceFactory[name] = func() any {
		return factory()
	}
}

// GetInstance 获取服务实例
// name 服务名，方法内部会将服务名的首字母小写
func GetInstance[T any](name string) T {
	mu.Lock() // 加锁：确保并发安全
	defer mu.Unlock()

	name = myutil.LowerFirst(name) // 服务名首字母小写

	// 1. 从缓存获取实例（修正：直接获取 any 类型实例）
	if instance, ok := serviceInstances[name]; ok {
		val, ok := instance.(T) // 类型断言并检查合法性
		if !ok {
			panic("instance type mismatch: " + name + " (expected " + reflect.TypeOf((*T)(nil)).Elem().String() + ")")
		}
		return val
	}

	// 2. 缓存未命中，通过工厂创建实例
	factory, ok := serviceFactory[name]
	if !ok {
		panic("service not registered: " + name)
	}

	instance := factory()
	serviceInstances[name] = instance // 此时 instance 为 any 类型，可正常赋值

	// 类型断言并检查合法性
	val, ok := instance.(T)
	if !ok {
		panic("factory return type mismatch: " + name + " (expected " + reflect.TypeOf((*T)(nil)).Elem().String() + ")")
	}
	return val
}

func Exists(name string) bool {
	_, ok := serviceFactory[name]
	return ok
}

func Refresh() {
	mu.Lock() // 添加锁确保并发安全
	defer mu.Unlock()

	for name, factory := range serviceFactory {
		if _, ok := serviceInstances[name]; !ok {
			logrus.Debug(" service create instance: " + name)
			serviceInstances[name] = factory()
		}
	}
	logrus.Info("service instances refreshed.")
}
